import thin_render from "./thin_render.mjs";
import { after, clearafterqueue } from "./delay_render.mjs";
import { thin } from "../thin3.mjs";
import render_helper from "./render_helper.mjs";

/**
 * 路由模板渲染函数 - 用于处理前端路由并渲染对应的模板内容
 * @param {HTMLElement} container - 容器元素，用于放置route组件
 * @param {Object} template - 路由模板配置对象，包含路由规则和对应的模板
 *                           格式示例: {
 *                             route: {
 *                               '/user/:id': userTemplate,
 *                               '/post/:id': postTemplate
 *                             },
 *                             default: defaultTemplate
 *                           }
 */
export default function (container, template) {
  // 创建自定义route元素作为路由容器
  let element = document.createElement("route");

  // 使用render_helper处理模板，应用模板的基础属性和事件
  render_helper(element, template);

  // 将route元素添加到指定容器中
  container.append(element);
  // 在route元素上存储路由配置，方便后续访问
  element.thin_route = template;

  // 将渲染函数加入延迟渲染队列，确保DOM更新后执行
  after(render);

  // 仅在页面首次使用route时绑定popstate事件
  // 用于处理浏览器前进/后退操作时的路由变化
  if (!nearest_route(container)) {
    window.addEventListener("popstate", (e) => {
      render();
      clearafterqueue();
    });
  }

  /**
   * 查找最近的route祖先节点
   * 用于确定是否已经存在route元素，避免重复绑定事件
   * @param {HTMLElement} node - 起始节点
   * @returns {HTMLElement|null} 找到的route节点或null
   */
  function nearest_route(node) {
    return node.closest("route");
  }

  /**
   * 路由渲染核心函数
   * 1. 根据当前URL hash匹配路由规则
   * 2. 提取路由参数
   * 3. 渲染对应的模板内容
   */
  function render() {
    // 清空route元素当前内容，准备重新渲染
    thin(element).empty();
    // 获取当前浏览器URL中的hash部分作为路由路径
    let currenthashpath = document.location.hash;

    // 获取所有配置的路由规则
    let routes = Object.keys(template.route);
    for (let i = 0; i < routes.length; i++) {
      let route = routes[i];
      let param;

      // 将路由规则中的动态参数(:param)转换为正则表达式
      // 例如: /user/:id => /user/([.\-\w]+)
      // 支持参数名中包含字母、数字、下划线、点和横线
      let regstr = route.replace(/:[.\-\w]+/g, (m) => {
        if (!param) param = {};
        param[m.slice(1)] = undefined;
        return "([.\\-\\w]+)";
      });

      // 构建完整的路由匹配正则，确保精确匹配
      let reg = new RegExp("^".concat(regstr, "(/|$)"));
      let matchs = currenthashpath.match(reg);

      // 如果找到匹配的路由规则
      if (matchs) {
        console.log({ matchs });
        element.thin_hashpath = matchs[0];
        // 提取路由参数值并保存
        if (matchs.length > 2) {
          for (i = 1; i < matchs.length - 1; i++) {
            param[Object.keys(param)[i - 1]] = matchs[i];
          }
          // 将提取的参数存储在route元素上，供模板使用
          element.thin_param = param;
        }

        // 渲染匹配路由对应的模板内容
        thin_render(element, template.route[route] || "");
        return;
      }
    }

    // 如果没有匹配的路由规则，渲染默认模板（如果存在）
    if (template.default) thin_render(element, template.default);
  }
}
